export class SoundRecording{ // 录音
    mediaRecorder: MediaRecorder | null;
    stream: MediaStream | null;
    chunks: any[];
    endCallback: any[];
    constructor() {
        this.mediaRecorder = null; // 录音对象
        this.stream = null; // 当前轨道
        this.chunks = []; // 录音缓存
        this.endCallback = []; // 录音结束回调
    }
    create() { // 创建一个录音任务
        return new Promise((resolve, reject) => {
            this.resetState();
            navigator.mediaDevices.getUserMedia({audio: true}).then((stream) => {
                this.stream = stream;
                this.mediaRecorder = new MediaRecorder(stream, { audioBitsPerSecond: 128000, mimeType: "audio/webm;codecs=opus" });
                resolve({code: 1, message: '创建成功'});
            }).catch((err) => {
                reject(err);
            });
        });
    }
    start() { // 开始录音
        return new Promise((resolve, reject) => {
            this.judgeMediaRecorderIs().then((mediaRecorder: MediaRecorder) => {
                // start(100); 每100毫秒生成一个数据可用事件
                mediaRecorder.start();
                // 完成一次录制片段后触发
                mediaRecorder.addEventListener('dataavailable', (e) => {
                    this.chunks.push(e.data);
                });
                resolve({code: 1, message: '开始录制'});
            }).catch((err) => {
                reject(err);
            });
        });
    }
    stop() { // 结束录音
        return new Promise((resolve, reject) => {
            this.judgeMediaRecorderIs().then((mediaRecorder: MediaRecorder) => {
                if (mediaRecorder.state === 'inactive') {
                    return reject({code: 0, message: '已结束'});
                };
                mediaRecorder.stop();
                this.stream.getTracks().forEach((track) => { track.stop(); });
                // 监听结束录制
                mediaRecorder.addEventListener('stop', (e: any) => {
                    resolve({code: 1, message: '录制结束'});
                    // 如果录制结束的回调，就执行回到
                    this.endCallback.forEach((callback) => {
                        callback();
                        this.endCallback.shift();
                    });
                });
            }).catch((err) => {
                reject(err);
            });
        });
    }
    download() { // 下载
        return new Promise((resolve, reject) => {
            this.handleChunksToBolb().then((blob: Blob) => {
                let url = URL.createObjectURL(blob);
                let a = document.createElement('a');
                a.href = url;
                // 也可以是 'audio.ogg'
                a.download = 'audio.wav';
                a.click();
                resolve(url);
            }).catch((err) => {
                reject(err);
            });
        });
    }
    viewRecording() { // 播放url
        return new Promise((resolve, reject) => {
            this.handleChunksToBolb().then((blob: Blob) => {
                let url = URL.createObjectURL(blob);
                resolve(url);
            }).catch((err) => {
                reject(err);
            });
        });
    }
    toFile() { // 转file对象
        return new Promise((resolve, reject) => {
            this.handleChunksToBolb().then((blob: Blob) => {
                resolve(new File([blob], 'audio.wav', { type: 'audio/wav' }));
            }).catch((err) => {
                reject(err);
            });
        });
    }
    handleChunksToBolb() { // 转bolb
        return new Promise((resolve, reject) => {
            this.judgeChunksIs().then((chunks: any) => {
                // 也可以是 'audio/ogg;codecs=opus'
                let blob = new Blob(chunks, { type: 'audio/wav;codecs=opus' })
                resolve(blob);
            }).catch((err) => {
                reject(err);
            });
        });
    }
    judgeChunksIs() { // 判断是否有录制缓存
        return new Promise((resolve, reject) => {
            let chunks = this.chunks;
            if (chunks.length === 0) {
                return reject({code: 0, message: '没有录制的缓冲'});
            };
            return resolve(chunks);
        });
    }
    judgeMediaRecorderIs() { // 判断是否创建了录音任务
        return new Promise((resolve, reject) => {
            let mediaRecorder = this.mediaRecorder;
            if (!mediaRecorder) { return reject({code: 0, message: '请先创建一个录制对象'}); };
            resolve(mediaRecorder);
        });
    }
    setEndCallback(callback) { // 存结束回调
        this.endCallback.push(callback);
    }
    resetState() { // 重置状态
        this.chunks = [];
        this.mediaRecorder = null;
        this.stream = null;
    }
};
